<template>
  <div>
    <div style="background:#fff">
      <span class="upload1" v-show="this.isupload=='1'||this.isupload=='2'">
        <slot/>
        <input class="change" id="id" type="file" @change="handleFileChange2" ref="inputer">
      </span>
      <ul id="content" v-show="this.imgpath!==''&&this.imgpath!==undefined">
        <li @click="showPic" v-if="this.wordfiletype == 'jpg' || this.wordfiletype == 'png'">
          <img :src="this.imgpath" alt style="height:60px">
        </li>
        <a
          :href="this.imgpath"
          target="view_window"
          style="display:inline-block;cursor:pointer"
          v-else
        >{{wordfilename}} 下载</a>
      </ul>
      <div class="picContent" v-show="isshow" @click="hidepic">
        <img
          :src="this.imgpath"
          alt
          style="height:auto;position:relative;display:block;margin:0 auto;"
        >
      </div>
    </div>
    <!-- <div v-if="this.localfiletype=='02'&&this.wordfilename!=''" style="margin:10px 0">
      <p><a :href="this.imgpath" target="view_window" style="display:inline-block;cursor:pointer">{{wordfilename}} 下载</a></p>
    </div>-->
  </div>
</template>
<style>
</style>

<script>
import SparkMD5 from "spark-md5";

const baseUrl = "http://111.231.227.116:5000";
let chunkSize = 1 * 1024 * 1024;

let file = null;
let fileSize = 0;
let chunks = 5;
let blobSlice;
let currentChunk = 0;
let fileReader;

export default {
  watch: {
    imagefile() {
      if (this.imagefile) {
        this.imgpath = this.imagefile[this.tn];
        if (
          this.imgpath &&
          this.imgpath.length > 0 &&
          this.imgpath.split(".").length > 0
        ) {
          this.wordfiletype = this.imgpath.split(".")[
            this.imgpath.split(".").length - 1
          ];
        }
        console.log(this.imgpath);
      } else {
        this.imgpath = "";
      }
    }
  },
  props: {
    tn: {
      type: String
    },
    imagefile: {
      type: Object
    },
    localfiletype: {
      type: String
    },
    isupload: {
      type: String
    }
  },

  data() {
    return {
      shouPic: true,
      debug: false,
      wordfilename: "",
      wordfiletype: "",
      ts: this.newStore(),
      aa: this.newStore(),
      list: [],
      imgpath: "",
      isshow: false,
      localFilename: "查看"
    };
  },
  methods: {
    changePic(pic) {
      this.imgpath = pic;
      this.imagefile[this.tn] = pic;
      if (
        this.imgpath &&
        this.imgpath.length > 0 &&
        this.imgpath.split(".").length > 0
      ) {
        this.wordfiletype = this.imgpath.split(".")[
          this.imgpath.split(".").length - 1
        ];
      }
      // alert(this.tn);
      // this.$emit('getTestinput', this.imgpath, this.tn);
    },
    showPic() {
      this.isshow = true;
    },
    hidepic() {
      this.isshow = false;
    },
    handleFileChange() {
      const inputDOM = this.$refs.inputer;
      const [tfile] = inputDOM.files;
      file = tfile;
      if (file == undefined) {
        return;
      }
      if (tfile.type == 'image/jpeg' || tfile.type == 'image/png') {
        this.errText = "";
        if (!file) {
          return;
        }
        fileSize = Math.floor(file.size);

        // alert(fileSize);
        // 提示
        this.localFilename = file.name;
        this.responseChange(file);
      } else {
        this.$message('只能上传图片且格式为jpg,png格式文件');
      }
    },
    handleFileChange2() {
      const inputDOM = this.$refs.inputer;
      const [tfile] = inputDOM.files;
      file = tfile;
      if (file == undefined) {
        return;
      }
      if (tfile.type == "image/jpeg" || tfile.type == "image/png") {
        this.$message("只能上传图片且格式为jpg,png格式文件");
      } else {
        this.wordfilename = tfile.name;

        this.errText = "";
        if (!file) {
          return;
        }
        fileSize = Math.floor(file.size);

        // alert(fileSize);
        // 提示
        this.localFilename = file.name;
        this.responseChange(file);
      }
    },
    async upload(i, fileMd5Value, pchunks) {
      return new Promise(resolve => {
        // 构造一个表单，FormData是HTML5新增的
        const end =
          (i + 1) * chunkSize >= file.size ? file.size : (i + 1) * chunkSize;
        const form = new FormData();
        form.append("data", file.slice(i * chunkSize, end)); // file对象的slice方法用于切出文件的一部分
        form.append("total", pchunks); // 总片数
        form.append("index", i); // 当前是第几片
        form.append("fileMd5Value", fileMd5Value);
        this.spost(this.ts, `${baseUrl}/upload`, form)
          .then(ts => {
            resolve(ts.d.desc);
          })
          .catch(ts => {
            resolve(ts.d.desc);
          });
      });
    },
    async checkAndUploadChunk(fileMd5Value, chunkList) {
      return new Promise(resolve => {
        chunks = Math.ceil(fileSize / chunkSize);
        const promiselist = [];

        for (let i = 0; i < chunks; i += 1) {
          const exit = chunkList.indexOf(`${i}`) > -1;
          // 如果已经存在, 则不用再上传当前块
          if (!exit) {
            promiselist.push(this.upload(i, fileMd5Value, chunks));
          }
        }
        Promise.all(promiselist).then(() => {
          resolve();
        });
      });
    },

    async checkFileMD5(fileName, fileMd5Value) {
      return new Promise(resolve => {
        const url = `${baseUrl}/check/file`;
        this.sget(this.ts, url, { fileName, fileMd5Value }).then(ts => {
          resolve(ts.d);
        });
      }).catch(reject => {
        reject();
      });
    },

    notifyServer(fileMd5Value) {
      // alert(111111111111111111);
      const url = `${baseUrl}/merge?md5=${fileMd5Value}&fileName=${
        file.name
      }&size=${file.size}`;
      this.sget(this.ts, url, {}).then(ts => {
        const pic = `${baseUrl}/nodeServer/uploads/${ts.d.fname}`;
        console.log(pic);
        // alert(22222222222222222222);
        this.changePic(pic);
      });
    },

    loadNext() {
      const start = currentChunk * chunkSize;
      const end =
        start + chunkSize >= file.size ? file.size : start + chunkSize;

      fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
    },
    async md5File(pfile) {
      return new Promise(resolve => {
        blobSlice =
          File.prototype.slice ||
          File.prototype.mozSlice ||
          File.prototype.webkitSlice;

        chunkSize = pfile.size / chunks;

        currentChunk = 0;
        const spark = new SparkMD5.ArrayBuffer();
        fileReader = new FileReader();

        fileReader.onload = e => {
          spark.append(e.target.result);

          currentChunk += 1;

          if (currentChunk < chunks) {
            this.loadNext();
          } else {
            // const cur = +(new Date());
            // console.log('finished loading');
            // alert(spark.end() + '---' + (cur - pre)); // Compute hash
            const result = spark.end();
            resolve(result);
          }
        };

        fileReader.onerror = () => {
          console.warn("oops, something went wrong.");
        };

        this.loadNext();
      }).catch(reject => {
        reject();
      });
    },

    async responseChange(pfile) {
      // 第一步：按照 修改时间+文件名称+最后修改时间-->MD5
      // 显示文件校验进度

      const fileMd5Value = await this.md5File(pfile);

      const fileName = fileMd5Value.concat(
        ".",
        pfile.name.split(".")[pfile.name.split(".").length - 1]
      );
      // 第二步：校验文件的MD5
      const result = await this.checkFileMD5(fileName, fileMd5Value);
      console.log(result);

      // 如果文件已存在, 就秒传
      if (result.file) {
        const pic = `${baseUrl}/nodeServer/uploads/${fileName}`;
        // console.log(this.imgpath);
        this.changePic(pic);
        return;
      }
      // let exit = false
      // 显示文件上传进度

      this.checkAndUploadChunk(fileMd5Value, result.chunkList).then(() => {
        console.log("notifyServer");
        this.notifyServer(fileMd5Value);
      });

      // 第四步: 通知服务器所有分片已上传完成

      // console.log(this.notifyServer);
    },
    verificationPicFile(pfile) {
      const fileTypes = [".jpg", ".png"];
      const filePath = pfile.value;
      // 当括号里面的值为0、空字符、false 、null 、undefined的时候就相当于false
      if (filePath) {
        let isNext = false;
        const fileEnd = filePath.substring(filePath.indexOf("."));
        for (let i = 0; i < fileTypes.length; i += 1) {
          if (fileTypes[i] === fileEnd) {
            isNext = true;
            break;
          }
        }
        if (!isNext) {
          alert("不接受此文件类型");
          pfile.value = "";
          return false;
        }
      } else {
        return false;
      }
      return true;
    }
  }
};
</script>
<style scoped lang="stylus" rel="stylesheet/stylus">
.info-wrapper .info-content .upload-btn[data-v-0cbaa4e1] {
  background: #fff;
}

.picContent {
  position: fixed;
  top: 120px;
  right: 0;
  left: 0;
  margin: 0;
  margin: 0 auto;
  z-index: 5000;
  width: 70%;
  overflow: auto;
  height: 70%;
}

.upload1 {
  padding: 7px 3px;
  height: 33px;
  line-height: 33px;
  position: relative;
  background: #69f;
  border-radius: 3px;
  text-decoration: none;
  color: #fff;

  .change {
    position: absolute;
    overflow: hidden;
    right: 0;
    top: 0;
    opacity: 0;
    width: 86px;
    height: 33px;
  }
}

ul {
  margin-top: 2px;
  font-size: 14px;
}
</style>
